#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""get information of dispatcher platform port  采集分流平台的端口
@author : buptzjj
@license : Copyright@haohandata
@version : 1.0
@todo : 创建脚本  20170728  by buptzjj
"""

import sys
import os
import time

plugins_path = os.getenv("INSPECTOR_HOME") + "/plugins"
sys.path.append(plugins_path + "/common/")

import tools
from dispatch_platform import *
import get_ip_list
import get_snmp_info
from multiprocessing import Process, Lock
import traceback

ERR_FLAG = "No Such Object available on this agent at this OID"
TIME_OUT = 30
SECTION = "dispatcher"
KEY = "appadmin_password"
PASSWORD = tools.get_config_option(SECTION, KEY)
MID_FILE_PATH = plugins_path + "/collect/intermediate_file/div.txt"
MID_TRAFFIC_FILE_PATH = plugins_path + "/collect/intermediate_file/div_traffic.txt"
LOGGER_FILE = "dispatcher_traffic_collect.log"

logger = tools.get_logger(LOGGER_FILE)


def print_exception_stack():
    exc_type, exc_value, exc_traceback = sys.exc_info()
    error = str(repr(traceback.format_exception(exc_type, exc_value, exc_traceback)))
    logger.error(error)
    return error


def dealRuianTraffic(
    ip, check_time, in_traffic_list, out_traffic_list, in_pps_list, out_pps_list
):
    with open(MID_TRAFFIC_FILE_PATH, "rw+") as f:
        src_in_traffic_list = []
        src_out_traffic_list = []
        src_in_pps_list = []
        src_out_pps_list = []
        for line in f.readlines():
            if ip in line and len(line.split("\t")) == 6:
                collect_time = line.split("\t")[0]
                src_in_traffic_list = line.split("\t")[2].split(",")
                src_out_traffic_list = line.split("\t")[3].split(",")
                src_in_pps_list = line.split("\t")[4].split(",")
                src_out_pps_list = line.split("\t")[5].split(",")
        f.write(
            "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\n".format(
                str(check_time),
                ip,
                ",".join(map(str, in_traffic_list)),
                ",".join(map(str, out_traffic_list)),
                ",".join(map(str, in_pps_list)),
                ",".join(map(str, out_pps_list)),
            )
        )
        if len(src_in_traffic_list) != 0 and len(src_out_traffic_list) != 0:
            in_traffic_list = computeRate(
                check_time, collect_time, in_traffic_list, src_in_traffic_list
            )
            out_traffic_list = computeRate(
                check_time, collect_time, out_traffic_list, src_out_traffic_list
            )
        if len(src_in_pps_list) != 0 and len(src_out_pps_list) != 0:
            in_pps_list = computePacketRate(
                check_time, collect_time, in_pps_list, src_in_pps_list
            )
            out_pps_list = computePacketRate(
                check_time, collect_time, out_pps_list, src_out_pps_list
            )

        return (in_traffic_list, out_traffic_list, in_pps_list, out_pps_list)


def computePacketRate(now, before, now_traffic_list, before_traffic_list):
    diff_time = int(now) - int(before)
    rate_list = []
    for now_traffic, before_traffic in zip(now_traffic_list, before_traffic_list):
        diff_traffic = int(now_traffic) - int(before_traffic)
        rate = diff_traffic / diff_time
        rate_list.append(rate)
    return rate_list


def computeRate(now, before, now_traffic_list, before_traffic_list):
    diff_time = int(now) - int(before)
    rate_list = []
    for now_traffic, before_traffic in zip(now_traffic_list, before_traffic_list):
        diff_traffic = int(now_traffic) - int(before_traffic)
        rate = diff_traffic * 8 / 1000 / diff_time
        rate_list.append(rate)
    return rate_list


def task(ip, lock):
    check_time = time.strftime("%s", time.localtime())
    mfc = get_manufacturer(ip)
    if mfc == "恒为":
        div_obj = DivOptiway(ip, PASSWORD)
    elif mfc == "锐安":
        div_obj = DivRuian(ip, PASSWORD)
    else:
        div_obj = DispatchPlatform(ip, PASSWORD)
    if_name_list = div_obj.get_if_name()
    if_bandwidth_list = div_obj.get_if_bandwidth()
    if_status_list = div_obj.get_if_status()
    if_in_traffic_list = div_obj.get_if_in_traffic()
    if_out_traffic_list = div_obj.get_if_out_traffic()
    if_in_pps_list = div_obj.get_if_in_pps()
    if_out_pps_list = div_obj.get_if_out_pps()
    if_in_err_pkts_list = div_obj.get_if_in_err_pkts()
    if_in_err_fcs_pkts_list = div_obj.get_if_in_err_fcs_pkts()
    if_out_err_pkts_list = div_obj.get_if_out_err_pkts()
    if_out_err_fcs_pkts_list = div_obj.get_if_out_err_fcs_pkts()
    lock.acquire(timeout=60)
    try:
        (
            if_in_err_pps_list,
            if_in_err_fcs_pps_list,
            if_out_err_pps_list,
            if_out_err_fcs_pps_list,
        ) = dealRuianTraffic(
            ip,
            check_time,
            if_in_err_pkts_list,
            if_in_err_fcs_pkts_list,
            if_out_err_pkts_list,
            if_out_err_fcs_pkts_list,
        )
        with open(MID_FILE_PATH, "w") as f:
            for (
                if_name,
                if_bandwidth,
                if_status,
                if_in_traffic,
                if_out_traffic,
                if_in_pps,
                if_out_pps,
                if_in_err_pps,
                if_in_err_fcs_pps,
                if_out_err_pps,
                if_out_err_fcs_pps,
            ) in zip(
                if_name_list,
                if_bandwidth_list,
                if_status_list,
                if_in_traffic_list,
                if_out_traffic_list,
                if_in_pps_list,
                if_out_pps_list,
                if_in_err_pps_list,
                if_in_err_fcs_pps_list,
                if_out_err_pps_list,
                if_out_err_pps_list,
            ):
                fields = if_name.split("/")
                if len(fields) > 0:
                    if mfc == "恒为":
                        board_id = fields[0]
                        slot_name = fields[1]
                    elif mfc == "锐安":
                        board_id = fields[1]
                        slot_name = fields[0][:1]
                    else:
                        board_id = fields[0]
                        slot_name = fields[1]
                if ip.find(":") >= 0:
                    ip = ip.split(":")[0]
                print(
                    "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}".format(
                        check_time,
                        ip,
                        if_name,
                        if_bandwidth,
                        if_status,
                        if_in_traffic,
                        if_out_traffic,
                        board_id,
                        slot_name,
                        if_in_pps,
                        if_out_pps,
                        if_in_err_pps,
                        if_in_err_fcs_pps,
                        if_out_err_pps,
                        if_out_err_fcs_pps,
                        "div_traffic",
                    )
                )
                f.write(
                    "{0}\t{1}\t{2}\t{3}\t{4}\n".format(
                        ip,
                        check_time,
                        if_name,
                        if_status,
                        (int(if_in_traffic) + int(if_out_traffic)),
                    )
                )
    except Exception:
        print_exception_stack()
    finally:
        lock.release()


def main():
    div_ip_list = get_ip_list.get_ip_list("dispatch_platform")
    lock = Lock()
    process_list = []
    for ip in div_ip_list:
        p = Process(
            target=task,
            args=(
                ip,
                lock,
            ),
        )
        process_list.append(p)
        p.start()
    for p in process_list:
        p.join()


if __name__ == "__main__":
    main()
